package com.zx.game2048;

import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Point;
import android.os.Build;
import android.support.annotation.RequiresApi;
import android.support.v7.app.AlertDialog;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.GridLayout;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by zhoux on 2017/5/20.
 * 注释：自定义布局
 */

public class GameView extends GridLayout {
    public GameView(Context context) {
        super(context);
        initGameView();
    }

    public GameView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initGameView();
    }

    public GameView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initGameView();
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public GameView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        initGameView();
    }

    public void initGameView() {


        setColumnCount(4);
        setBackgroundColor(0xffbdafc0);

        setOnTouchListener(new OnTouchListener() {
            private float startX, startY, offsetX, offsetY;

            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        startX = event.getX();
                        startY = event.getY();
                        break;
                    case MotionEvent.ACTION_UP:
                        offsetX = event.getX() - startX;
                        offsetY = event.getY() - startY;
                        if (Math.abs(offsetX) > Math.abs(offsetY)) {
                            if (offsetX < -15) {
                                Log.d("GameView:", "left");
//left
                                swipeLeft();
                            } else if (offsetX > 15) {
//right
                                Log.d("GameView:", "right");
                                swipeRight();

                            } else {
                            }
                        } else {
                            if (offsetY < -15) {
//up
                                Log.d("GameView:", "up");
                                swipeUp();

                            } else if (offsetY > 15) {
//down

                                Log.d("GameView:", "down");
                                swipeDown();

                            } else {
                            }
                        }

                        break;

                    default:
                        break;
                }
                return true;
            }
        });
    }

    private void swipeDown() {
        boolean merge = false;
        for (int x = 0; x < 4; x++) {
            for (int y = 3; y >= 0; y--) {
                for (int y1 = y - 1; y1 >= 0; y1--) {
                    if (cardsMap[x][y1].getNum() > 0) {
                        if (cardsMap[x][y].getNum() <= 0) {
                            cardsMap[x][y].setNum(cardsMap[x][y1].getNum());
                            cardsMap[x][y1].setNum(0);


                            y++;
                            merge = true;
                        } else if (cardsMap[x][y].equals(cardsMap[x][y1])) {
                            cardsMap[x][y].setNum(cardsMap[x][y].getNum() * 2);
                            cardsMap[x][y1].setNum(0);


                            MainActivity.getMainActivity().addScre(cardsMap[x][y].getNum());
                            merge = true;
                        }
                        break;

                    }
                }
            }
        }

        if (merge) {
            addRandomNum();
            checkComplete();
        }
    }

    private void swipeUp() {
        boolean merge = false;
        for (int x = 0; x < 4; x++) {
            for (int y = 0; y < 4; y++) {
                for (int y1 = y + 1; y1 < 4; y1++) {
                    if (cardsMap[x][y1].getNum() > 0) {
                        if (cardsMap[x][y].getNum() <= 0) {
                            cardsMap[x][y].setNum(cardsMap[x][y1].getNum());
                            cardsMap[x][y1].setNum(0);


                            y--;
                            merge = true;
                        } else if (cardsMap[x][y].equals(cardsMap[x][y1])) {
                            cardsMap[x][y].setNum(cardsMap[x][y].getNum() * 2);
                            cardsMap[x][y1].setNum(0);


                            MainActivity.getMainActivity().addScre(cardsMap[x][y].getNum());
                            merge = true;
                        }
                        break;

                    }
                }
            }
        }

        if (merge) {
            addRandomNum();
            checkComplete();
        }
    }

    //右划逻辑
    private void swipeRight() {
        boolean merge = false;
        for (int y = 0; y < 4; y++) {
            for (int x = 3; x >= 0; x--) {
                for (int x1 = x - 1; x1 >= 0; x1--) {
                    if (cardsMap[x1][y].getNum() > 0) {
                        if (cardsMap[x][y].getNum() <= 0) {
                            cardsMap[x][y].setNum(cardsMap[x1][y].getNum());
                            cardsMap[x1][y].setNum(0);


                            x++;
                            merge = true;
                        } else if (cardsMap[x][y].equals(cardsMap[x1][y])) {
                            cardsMap[x][y].setNum(cardsMap[x][y].getNum() * 2);
                            cardsMap[x1][y].setNum(0);


                            MainActivity.getMainActivity().addScre(cardsMap[x][y].getNum());
                            merge = true;
                        }
                        break;

                    }
                }
            }
        }

        if (merge) {
            addRandomNum();
            checkComplete();
        }
    }

    //左划逻辑
    private void swipeLeft() {
        boolean merge = false;

        for (int y = 0; y < 4; y++) {
            for (int x = 0; x < 4; x++) {
                for (int x1 = x + 1; x1 < 4; x1++) {
                    if (cardsMap[x1][y].getNum() > 0) {
                        if (cardsMap[x][y].getNum() <= 0) {
                            cardsMap[x][y].setNum(cardsMap[x1][y].getNum());
                            cardsMap[x1][y].setNum(0);


                            x--;
                            merge = true;
                        } else if (cardsMap[x][y].equals(cardsMap[x1][y])) {
                            cardsMap[x][y].setNum(cardsMap[x][y].getNum() * 2);
                            cardsMap[x1][y].setNum(0);


                            MainActivity.getMainActivity().addScre(cardsMap[x][y].getNum());
                            merge = true;
                        }
                        break;

                    }
                }
            }
        }


        if (merge) {
            addRandomNum();
            checkComplete();
        }
    }

    private void checkComplete() {
        boolean complete = true;
        ALL:
        for (int y = 0; y < 4; y++) {
            for (int x = 0; x < 4; x++) {
                if (cardsMap[x][y].getNum() == 0 ||
                        (x > 1 && cardsMap[x][y].equals(cardsMap[x - 1][y])) ||
                        (x < 3 && cardsMap[x][y].equals(cardsMap[x + 1][y])) ||
                        (y > 0 && cardsMap[x][y].equals(cardsMap[x][y - 1])) ||
                        (y < 3 && cardsMap[x][y].equals(cardsMap[x][y + 1]))) {
//没有结束
                    complete = false;
                    break ALL;
                }
            }
        }

        if (complete) {
            new AlertDialog.Builder(getContext()).setTitle("你好").setMessage("游戏结束").setPositiveButton("重来", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    startGame();
                }
            }).setCancelable(false).show();
        }

    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        //布局宽高设置,计算每张卡片宽高
        int cardWidth = (Math.min(w, h) - 10) / 4;

        addCards(cardWidth, cardWidth);
        startGame();
    }

    private void addCards(int cardWidth, int carHeight) {
        Card c;
        for (int y = 0; y < 4; y++) {
            for (int x = 0; x < 4; x++) {
                c = new Card(getContext());
                c.setNum(0);
                addView(c, cardWidth, carHeight);
                cardsMap[x][y] = c;
            }
        }
    }

    private Card[][] cardsMap = new Card[4][4];
    private List<Point> emptyPoint = new ArrayList<>();


    public void startGame() {
        MainActivity.getMainActivity().clearScore();
        for (int y = 0; y < 4; y++) {
            for (int x = 0; x < 4; x++) {
                cardsMap[x][y].setNum(0);
            }
        }
        addRandomNum();//添加一个点

        addRandomNum();//添加两个点
//        addRandomNum();
//        addRandomNum();
//        addRandomNum();
//        addRandomNum();
//        addRandomNum();
//        addRandomNum();
//        addRandomNum();
    }

    /**
     *
     */
    private void addRandomNum() {
        emptyPoint.clear();
        for (int y = 0; y < 4; y++) {
            for (int x = 0; x < 4; x++) {
                if (cardsMap[x][y].getNum() <= 0) {
                    emptyPoint.add(new Point(x, y));
                }
            }
        }
        Point p = emptyPoint.remove((int) (Math.random() * emptyPoint.size()));
        switch (MODEL) {
            case EASY:
                cardsMap[p.x][p.y].setNum(easy());
                break;
            case HARD:
                cardsMap[p.x][p.y].setNum(hard());
                break;
            default:
                break;
        }
    }

    public static final int HARD = 1;
    public static final int EASY = 0;
    private int MODEL = EASY;//难易模式

    public interface AfterSwitch {
        void after();
    }

    AfterSwitch afterSwitch;

    public void setAfterSwitch(AfterSwitch afterSwitch) {
        this.afterSwitch = afterSwitch;
    }

    public void switchModel(final int model) {
        new AlertDialog.Builder(getContext()).setTitle("切换模式").setMessage("切换模式需要重新开始，确定？").setPositiveButton("重来", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                MODEL = model;
                startGame();
                if (afterSwitch != null) {
                    afterSwitch.after();
                }
            }
        }).setCancelable(false).show();

    }

    private int easy() {
        return Math.random() > 0.1 ? 2 : 4;
    }

    private int hard() {
        if (Math.random() > 0.9) {
            return getANum();
        } else {
            return Math.random() > 0.1 ? 2 : 4;

        }
    }

    private int getANum() {

        if (Math.random() > 0.95) {
            return 512;
        }

        if (Math.random() > 0.9) {
            return 256;
        }
        if (Math.random() > 0.82) {
            return 128;
        }
        if (Math.random() > 0.72) {
            return 64;
        }
        if (Math.random() > 0.6) {
            return 32;
        }
        if (Math.random() > 0.5) {
            return 16;
        }
        if (Math.random() > 0.35) {
            return 8;
        }
        return 4;
    }
}
